package br.mikhas.task;

import static br.mikhas.util.Assert.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import br.mikhas.task.metadata.HolidayCalendar;
import br.mikhas.task.metadata.User;

public class TaskList {

	protected long number;

	/**
	 * The task list name
	 */
	protected String name;

	/**
	 * Task list owner users which may create, edit and execute tasks
	 */
	protected Collection<User> editors;

	/**
	 * Task list memeber users which may execute tasks
	 */
	protected Collection<User> members;

	private transient Collection<Task> tasks;

	/**
	 * Holiday calendars that applies to this task list
	 */
	protected Collection<HolidayCalendar> holidayCalendars;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		notEmpty(name);
		this.name = name;
	}

	/**
	 * Adds a new member to this list
	 * 
	 * @param member
	 *            The member to add
	 */
	public void addMember(User member) {
		if (!this.containsMember(member)) {
			notNull(member);
			if (this.members == null)
				this.members = new ArrayList<User>();

			this.members.add(member);
		}
	}

	/**
	 * Removes a member from the list
	 * 
	 * @param member
	 *            The member to be removed
	 */
	public void removeMember(User member) {
		if (member != null && this.members != null)
			this.members.remove(member);
	}

	/**
	 * Checks if list contains member
	 * 
	 * @param member
	 *            The member to check
	 * @return <tt>true</tt> if the member is on the list
	 */
	public boolean containsMember(User member) {
		if (member == null || this.members == null)
			return false;
		else
			return this.members.contains(member);
	}

	/**
	 * Adds a new editor to this list
	 * 
	 * @param editor
	 *            The editor to add
	 */
	public void addEditor(User editor) {
		if (!this.containsEditor(editor)) {
			notNull(editor);
			if (this.editors == null)
				this.editors = new ArrayList<User>();

			this.editors.add(editor);
		}
	}

	/**
	 * Removes a editor from the list
	 * 
	 * @param editor
	 *            The editor to be removed
	 */
	public void removeEditor(User editor) {
		if (editor != null && this.editors != null)
			this.editors.remove(editor);
	}

	/**
	 * Checks if list contains editor
	 * 
	 * @param editor
	 *            The editor to check
	 * @return <tt>true</tt> if the editor is on the list
	 */
	public boolean containsEditor(User editor) {
		if (editor == null || this.editors == null)
			return false;
		else
			return this.editors.contains(editor);
	}

	/**
	 * Checks if the user is a member of this task list
	 * 
	 * @param user
	 *            The user to check
	 * @return
	 */
	public boolean isMember(User user) {
		return this.containsMember(user);
	}

	/**
	 * Checks if the user is an editor of this task list
	 * 
	 * @param user
	 *            the user to check
	 * @return
	 */
	public boolean isEditor(User user) {
		return this.containsEditor(user);
	}

	/**
	 * Checks if this user is an editor or a member of this list
	 * 
	 * @param user
	 *            The user to check
	 * @return <tt>true</tt> if the given user is either a member or an editor
	 *         of this task list
	 */
	public boolean containsUser(User user) {
		return user == null ? false : this.containsMember(user)
				|| this.containsEditor(user);
	}

	public void setTasks(Collection<Task> tasks) {
		this.tasks = tasks;
	}

	public Collection<Task> getTasks() {
		return this.tasks;
	}

	@Override
	public String toString() {
		return "TaskList[" + this.number + " - " + this.name + ']';
	}

	/**
	 * Gets the list editors
	 * 
	 * @return
	 */
	public Collection<User> getEditors() {
		return Collections.unmodifiableCollection(this.editors);
	}

	/**
	 * Gets the list members
	 * 
	 * @return
	 */
	public Collection<User> getMembers() {
		return Collections.unmodifiableCollection(this.members);
	}

	public Collection<HolidayCalendar> getHolidayCalendars() {
		if (holidayCalendars == null)
			return Collections.emptyList();
		return Collections.unmodifiableCollection(holidayCalendars);
	}

	public void addTask(Task task) {
		if (this.tasks == null)
			this.tasks = new ArrayList<Task>();
		this.tasks.add(task);
		task.setList(this);
	}
}
